package com.socket.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.socket.server.config.Configuration;
import com.socket.server.request.ServerRequest;
import com.socket.server.request.SocketRequest;
import com.socket.server.service.ServerRequestService;
import com.socket.server.service.ServerRequestServiceFactory;
import com.socket.server.threadpool.ServerThreadPool;
import com.socket.util.Constants;

public class SocketServer extends Configuration{
	
	private ServerSocket ss;
	
	private final static ExecutorService threadPool = ServerThreadPool.fixedThreadPool(2);
	
	private final ServerRequestService service = ServerRequestServiceFactory.getService();
	
	public SocketServer(){
		try {
			ss = new ServerSocket(60000,10);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void start(){
		System.out.println("start server!!!");
		
		initConfig();
		while(true){
			try {
				Socket socket = ss.accept();
				
				//read the socket input stream and convert a ServerRequest
				Response response = new Response();
				ServerRequest request = new SocketRequest(socket,service,this,response);
				Future<?> future = threadPool.submit(request);
				if(getTimeout()>0){
					try {
						future.get(getTimeout(), TimeUnit.MILLISECONDS);
					} catch (InterruptedException | ExecutionException
							| TimeoutException e) {
						
						service.doTimeOut(response);
						System.out.println("server time out!!!");
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
